package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.aipFace.AipFaceTemplate;
import com.itheima.autoconfig.huanXin.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.UserInfoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Component
public class UserManager {
    @DubboReference
    private UserService userService;
    @Autowired
    private SmsTemplate smsTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private UserInfoService userInfoService;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /*
    调用service完成保存
     */
    public ResponseEntity save(User user) {
        Long userId = userService.save(user);
        return ResponseEntity.ok(userId);
    }

    /*
    通过手机号查找用户
     */
    public ResponseEntity findByPhone(String phone) {
        User user = null;
        try {//不报错时直接赋值
            user = userService.findByPhone(phone);
        } catch (Exception e) {
            //报错返回错误页面
            e.printStackTrace();
            return ResponseEntity.status(500).body(ErrorResult.error());
        }
        return ResponseEntity.ok(user);
    }

    /*
    发送验证码
     */
    public void sendSms(String phone) {
        //生产6位验证码
        String code = RandomUtil.randomNumbers(6);
        //为测试方便给验证码赋值
        code = "123456";
        //TODO  调用阿里云短信功能发送短信
        //smsTemplate.sendSms(phone,code);
        //把验证码存入redis有效期5分钟
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, code, Duration.ofMinutes(5));
    }

    /*
    注册或登录功能
     */
    public ResponseEntity regAndLogin(String phone, String verificationCode) {
        //取出redis里的验证码
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        //判断是否正确
        if (!redisCode.equals(verificationCode)) {
            //不正确返回错误页面
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        //定义一个布尔值来判断是注册还是登录
        boolean isNew;
        //通过手机号查询用户
        User user = userService.findByPhone(phone);
        //如果用户值为空 判为注册处理
        if (user == null) {
            //给用户赋值
            user = new User();
            user.setPhone(phone);
            user.setPassword("123456");
            //保存用户
            Long userId = userService.save(user);
            //给用户id赋值
            user.setId(userId);
            isNew = true;
            //向环信注册用户
            huanXinTemplate.register(userId);
        } else {
            //用户有值 判为登录
            isNew = false;
        }
        //为保护用户账号安全 把密码值先给为null值在生成令牌
        user.setPassword(null);
        //通过工具类把user对象转为map
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        //通过工具类生成令牌
        String token = JwtUtil.createToken(claims);
        //把user对象转为string类型方便存入redis
        String json = JSON.toJSONString(user);
        //存入redis key为token value为string格式的user 有效期7天
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));
        //登录或注册创建日志类记录
        Log log = new Log();
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.formatDate(new Date()));
        log.setPlace("黑马程序员");
        log.setEquipment("华为");
        if (isNew) {
            log.setType("0102");
        } else {
            log.setType("0101");
        }
        //把log发送到消息中间件
        rocketMQTemplate.convertAndSend("tanhua-user-log",log);
        //创建map 并赋值
        Map<String, Object> map = new HashMap<>();
        map.put("isNew", isNew);
        map.put("token", token);
        //向网页返回信息
        return ResponseEntity.ok(map);
    }

    //保存新用户基础信息
    public void saveUserInfoBase(UserInfo userInfo, String token) {
        //通过token获取user对象
        User user = findUserByToken(token);
        //给用户信息类id赋值
        userInfo.setId(user.getId());
        //调用业务层保存
        userInfoService.save(userInfo);
    }

    //保存新用户头像信息、修改头像信息
    public ResponseEntity saveUserInfoHead(MultipartFile headPhoto, String token) throws IOException {
        //通过token获取user
        User user = findUserByToken(token);
        //使用百度云人脸检测图片是否合格
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        //如果不合格
        if (!detect) {
            //返回错误信息
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }
        //可以运行到这代表合格 把图片保存到阿里云并获取url
        String path = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        //创建用户信息对象
        UserInfo userInfo = new UserInfo();
        //把id改为在token中获取的userid
        userInfo.setId(user.getId());
        //设置背景
        userInfo.setCoverPic(path);
        //设置头像
        userInfo.setAvatar(path);
        //调用业务层根据id修改信息
        userInfoService.update(userInfo);
        return ResponseEntity.ok(null);
    }

    //查询用户“我的”页面信息
    public ResponseEntity findUserInfoVo(Long userId) {
        //根据参数获取user信息对象
        UserInfo userInfo = userInfoService.findById(userId);
        //创建“我的”页面信息类
        UserInfoVo userInfoVo = new UserInfoVo();
        //封装“我的”页面信息类
        BeanUtil.copyProperties(userInfo, userInfoVo);
        if (userInfoVo.getAge() != null) {
            userInfoVo.setAge(userInfoVo.getAge().toString());
        }
        //返回页面
        return ResponseEntity.ok(userInfoVo);
    }

    //修改用户“我的”页面信息
    public void updateUserInfoBase(UserInfo userInfo) {
        //根据token获取user对象
        User user = UserHolder.get();
        //修改用户信息类id
        userInfo.setId(user.getId());
        //调用业务层根据id修改信息
        userInfoService.update(userInfo);
    }


    //根据token获取user功能
    public User findUserByToken(String token) {
        String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
        if (StrUtil.isEmpty(json)) {
            return null;
        }
        User user = JSON.parseObject(json, User.class);
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));
        return user;
    }
}
